package com.mundus.engine.resources;

import java.nio.FloatBuffer;

import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL13;
import org.lwjgl.opengl.GL20;
import org.lwjgl.util.vector.Matrix4f;
import org.lwjgl.util.vector.Vector2f;
import org.lwjgl.util.vector.Vector3f;
import org.lwjgl.util.vector.Vector4f;
import org.newdawn.slick.opengl.Texture;

import com.mundus.engine.assets.Log;

public class Shader {
	
	protected int _sId  = -1;	
	public int getShaderId(){return _sId;}
	
	public void apply(){
		if (_sId != -1)
			GL20.glUseProgram(this._sId);
		else
			Log.error("Shader not implemented");
	}
	
	public void remove(){
		GL20.glUseProgram(0);
	}
	
	public void setAttributeLocation(int index, String name){
		GL20.glBindAttribLocation(_sId, index, name);
	}
	
	public int getAttributeLocation(String name){
		return GL20.glGetUniformLocation(this._sId,name);
	}
	
	public void setMatrix(String name, Matrix4f value){
		FloatBuffer attributeBuffer = BufferUtils.createFloatBuffer(16);
		value.store(attributeBuffer); attributeBuffer.flip();
		GL20.glUniformMatrix4(getAttributeLocation(name), false, attributeBuffer);
		attributeBuffer.clear();
	}
	
	public void setTexture(String name, Texture texture, int index){		
		int texLoc = GL20.glGetUniformLocation(_sId, name);
		GL20.glUniform1i(texLoc, (index - GL13.GL_TEXTURE0));		
		GL13.glActiveTexture(index);
		GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_REPEAT);
		GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_REPEAT);
		GL11.glBindTexture(GL11.GL_TEXTURE_2D, texture.getTextureID());
		GL13.glActiveTexture(0);
	}
	
	public void setAttributef(String name, float value){
		int attribLoc = GL20.glGetUniformLocation(_sId, name);
		if (attribLoc != -1)
		   GL20.glUniform1f(attribLoc, value);
	}
	
	public void setAttributei(String name, int value){
		int attribLoc = GL20.glGetUniformLocation(_sId, name);
		if (attribLoc != -1)
		   GL20.glUniform1i(attribLoc, value);
	}
	
	public void setAttribute2f(String name, Vector2f value){
		int attribLoc = GL20.glGetUniformLocation(_sId, name);
		if (attribLoc != -1)
		   GL20.glUniform2f(attribLoc, value.x, value.y);
	}
	
	public void setAttribute3f(String name, Vector3f value){
		int attribLoc = GL20.glGetUniformLocation(_sId, name);
		if (attribLoc != -1)
		   GL20.glUniform3f(attribLoc, value.x, value.y, value.z);
	}
	
	public void setAttribute4f(String name, Vector4f value){
		int attribLoc = GL20.glGetUniformLocation(_sId, name);
		if (attribLoc != -1)
		   GL20.glUniform4f(attribLoc, value.x, value.y, value.z, value.w);
	}
}
